#include<iostream>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<cstdlib>

using namespace std;

//1.单个程序进程替换, 进程替换后后面的代码不执行
// int main()
// {
//     cout << "I am process, pid: " << getpid() << ", ppid: " << getppid() << endl;

//     execl("/usr/bin/ls", "ls", "-a", "-l", NULL);
//     // execlp("ls", "ls", "-a", "-l", nullptr);

//     //这里的代码不会被执行
//     cout << "I am process, pid: " << getpid() << ", ppid: " << getppid() << endl;

//     return 0;
// }

//2. 我们创建子进程进行进程替换, 使用execl execlp接口
// int main()
// {

//     pid_t id = fork();
//     if(id < 0)
//     {
//         perror("fork fail!");
//         return -1;
//     }
//     else if(id == 0)
//     {
//         cout << "before: I am process, pid: " << getpid() << ", ppid: " << getppid() << endl;

//         execl("/usr/bin/ls", "ls", "-a", "-l", nullptr);
//         // execlp("ls", "ls", "-a", "-l", nullptr);

//         cout << "after: I am process, pid: " << getpid() << ", ppid: " << getppid() << endl;
//         exit(0);
//     }

//     pid_t ret = waitpid(-1, nullptr, 0);
//     if(ret)
//     {
//         cout << "wait success!" << endl;
//     }
//     return 0;
// }

//3. 使用execv, execvp接口
// int main()
// {   
//     pid_t id = fork();
//     if(id == 0)
//     {
//         cout << "before: I am process, pid: " << getpid() << ", ppid: " << getppid() << endl;

//         char* const myargv[] = {"ls", "-a", "-l", nullptr};
//         // execv("/usr/bin/ls", myargv);
//         execvp("ls", myargv);


//         cout << "after: I am process, pid: " << getpid() << ", ppid: " << getppid() << endl;
//         exit(0);
//     }

//     pid_t ret = wait(nullptr);
//     if(ret)
//     {
//         cout << "wait success!" << endl;
//     }

//     return 0;
// }

//4.程序替换成自己写的可执行程序
// int main()
// {
//     pid_t id = fork();
//     if(id == 0)
//     {
//         cout << "before: I am process, pid: " << getpid() << ", ppid: " << getppid() << endl;

//         execl("./Ohterexe", "Ohterexe", nullptr);

//         cout << "after: I am process, pid: " << getpid() << ", ppid: " << getppid() << endl;
//         exit(0);
//     }

//     pid_t ret = wait(nullptr);
//     if(ret)
//     {
//         cout << "wait success!" << endl;
//     }

//     return 0;
// }

//5.使用excle来手动维护环境变量
char Myenv[] = "MY_ENV=8888";

int main()
{
    //自己添加环境变量
    extern char** environ;

    int n = putenv(Myenv);
    if(n < 0)
    {
        cout << "add environ error!" << endl;
    }
    else
    {
        cout << "add success..." << endl;
    }

    cout << getenv("MY_ENV") << endl;
    pid_t id = fork();
    if(id == 0)
    {
        cout << "before: I am process, pid: " << getpid() << ", ppid: " << getppid() << endl;
        
        char* const Myenv[] = {"MY_VALUE=66666", "MY_PATH=qifei", nullptr};
        execle("./Ohterexe", "Ohterexe", "-a", "-l", nullptr, environ);
        // execle("./Ohterexe", "Ohterexe", "-a", "-l", nullptr, Myenv);

        cout << "after: I am process, pid: " << getpid() << ", ppid: " << getppid() << endl;
        exit(1);
    }

    pid_t ret = wait(nullptr);
    if(ret)
    {
        cout << "wait success!" << endl;
    } 

    return 0;
}